﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace ExcelDna.Integration.Rtd
{
    // This is not a very elegant IObservable implementation - should not be public.
    // It basically represents a Subject 
    internal class ThreadPoolDelegateObservable : IExcelObservable
    {
        readonly ExcelFunc _func;
        bool _subscribed;

        public ThreadPoolDelegateObservable(ExcelFunc func)
        {
            _func = func;
        }

        public IDisposable Subscribe(IExcelObserver observer)
        {
            if (_subscribed) throw new InvalidOperationException("Only single Subscription allowed.");
            _subscribed = true;

            ThreadPool.QueueUserWorkItem(delegate
            {
                try
                {
                    object result = _func();
                    observer.OnNext(result);
                    observer.OnCompleted();
                }
                catch (Exception ex)
                {
                    // TODO: Log somehow
                    observer.OnError(ex);
                }
            });

            return new DummyDisposable();
        }

        class DummyDisposable : IDisposable
        {
            public void Dispose() { }
        }
    }
}
